#ifndef __GAF_PACKAGE_H__
#define __GAF_PACKAGE_H__

namespace GAF
{
	class Package;
}
typedef GAF::Package				GAF_CPackage;

#include "GAF_Image.h"

/// 磁盘目录资源类型
#define GAF_PACKAGE_DISK			"_Disk"

namespace GAF
{

	/// 资源包基类
	class Package
	{
	private:
		typedef STD_MAP<STD_STRING, Package*>
						PackageMap;

		typedef STD_MAP<STD_STRING, ImageHandle>
						ImageHandleMap;

	public:
		/// 创建或获得指定类型资源包
		template<class GAF_PKGTYPE>
		static Package*			GetPackage(const STD_STRING strPathName, const STD_STRING strType = GAF_PACKAGE_DISK);
		/// 创建或获得默认类型资源包
		static Package*			GetDefaultPackage(const STD_STRING strPathName);
		/// 销毁指定资源包
		static bool			DestroyOne(const STD_STRING strPathName);
		/// 销毁所有资源包
		static bool			DestroyAll();

	private:
		static PackageMap		ms_mapPackages;

	public:
		Package();
		virtual ~Package();

	public:
		/// 加载资源包
		bool				Load(const STD_STRING strPathName, const STD_STRING strKind = GAF_PACKAGE_DISK);
		/// 获得资源包内的图像句柄
		ImageHandle			GetImageHandle(const STD_STRING strImageName, _OUT ImageInfo& ii);
		/// 获得资源包内的图像
		Image*				GetImage(const STD_STRING strImageName);
//		UINT				GetData(const char szResName, BYTE* bData);
		/// 清除资源包
		bool				Release();
	
		/// 获得资源包所打开的路径
		STD_STRING			GetPath();
		/// 获得资源包类型
		STD_STRING			GetKind();

	public:
		/// 获得资源数量
		virtual int			GetCount();

	protected:
		/// 当加载资源包时
		virtual bool			OnLoad(const STD_STRING strPathName)
						{return false;}
		/// 当清除资源包时
		virtual bool			OnRelease()
						{return false;}
		/// 当读取资源包内的图像句柄时
		virtual ImageHandle		OnLoadImageHandle(const STD_STRING strImageName, _OUT ImageInfo& ii);
		/// 当销毁图像句柄时
		virtual bool			OnDestroyImageHandle(ImageHandle hImage);

	protected:
		/// 资源包路径
		STD_STRING			m_strPath;
		/// 资源包类型
		STD_STRING			m_strKind;
		/// 资源数
		int				m_nResCount;
		/// 资源包内图像句柄表
		ImageHandleMap			m_mapImageHandles;
	};

	template<class GAF_PKGTYPE>
	Package* Package::GetPackage(const STD_STRING strPathName, const STD_STRING strType)
	{
		GAF_CHECK_R(strType.size() != 0, NULL);

		Package* _pPackage = NULL;
		PackageMap::const_iterator _cit = ms_mapPackages.find(strPathName);
		if(_cit != ms_mapPackages.end())
			_pPackage = _cit->second;

		if(_pPackage == NULL)
		{
			GAF_CHECK_R(strPathName != "", NULL);

			_pPackage = GAF_NEW(GAF_PKGTYPE);

			if(!_pPackage->Load(strPathName, strType))
				return NULL;

			ms_mapPackages.insert(PackageMap::value_type(strPathName, _pPackage));
		}

		return _pPackage;
	}
}

#endif
